﻿using System.IO;
using System;
namespace YTPD.Lib
{
  public static class FFMpeg
  {
    public delegate void UpdateProgress(long current, long total);

    private static void EncodeFile(string fileArguments, UpdateProgress updateProgress, out long totalTime)
    {
      var p = new System.Diagnostics.Process
      {
        StartInfo =
        {
          FileName = "ffmpeg.exe",
          Arguments = fileArguments,
          UseShellExecute = false,
          CreateNoWindow = true,
          RedirectStandardOutput = true,
          RedirectStandardError = true,
        }
      };
      p.Start();

      GetProgressAndUpdate(p, updateProgress, out totalTime);

      p.WaitForExit();
    }

    private static void GetProgressAndUpdate(System.Diagnostics.Process p, UpdateProgress updateProgress, out long totalTime)
    {
      var errorStream = p.StandardError;
      totalTime = 0;
      while (!errorStream.EndOfStream)
      {
        var line = errorStream.ReadLine();
        if (line.Contains("Duration:"))
        {
          var durationKeyAndValue = line.Split(new char[] { ',' })[0];
          var durationValue = durationKeyAndValue.Substring(durationKeyAndValue.IndexOf(':') + 1);
          TimeSpan duration;
          TimeSpan.TryParse(durationValue, out duration);
          totalTime = Convert.ToInt64(duration.TotalSeconds);
        }
        else if (line.Contains("time="))
        {
          var timeSubstring = line.Substring(line.IndexOf("time="));
          var timeKeyAndValue = timeSubstring.Substring(0, timeSubstring.IndexOf(' '));
          var timeValueWithFractions = timeKeyAndValue.Split(new char[] { '=' })[1];
          var timeValue = Math.Floor(Convert.ToDouble(timeValueWithFractions) + 0.5);
          var currentTime = Convert.ToInt64(timeValue);

          updateProgress(currentTime, totalTime);
        }
      }
    }

    public static LocalAudioFile ConvertToAudioFile(LocalFlvFile flvFile, string outputFileName, UpdateProgress updateProgress)
    {
      var fileargs = "-i \"" + flvFile.FileName + "\" -y \"" + outputFileName + '"';

      long totalTime;
      EncodeFile(fileargs, updateProgress, out totalTime);

      return new LocalAudioFile { FileName = outputFileName, TotalTime = totalTime };
    }

    public static LocalVideoFile ConvertToVideoFile(LocalFlvFile flvFile, string outputFileName, UpdateProgress updateProgress)
    {
      var fileargs = "-i \"" + flvFile.FileName + "\" -y \"" + outputFileName + '"';

      long totalTime;
      EncodeFile(fileargs, updateProgress, out totalTime);

      return new LocalVideoFile { FileName = outputFileName, TotalTime = totalTime };
    }
  }
}